package hero.mps.config.jwt;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import io.jsonwebtoken.JwtException;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Calendar;
import java.util.Date;
import java.util.Map;

@Component
@Data
@ConfigurationProperties(prefix = "jwt")
public class JwtUtils {
    // 密钥
    private String secret;
    // 颁发者
    private String issuer;
    // 过期时间
    private int expiration;

    /**
     * 创建token
     * @param map
     * @return
     */
    public String generateToken(Map<String, String> map) {
        // 设置时间
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.MINUTE, expiration);
        // 创建build
        JWTCreator.Builder builder = JWT.create();
        // 设置自定义参数
        map.forEach((k, v) -> builder.withClaim(k, v));
        // 生成token
        String token = builder.withIssuer(issuer) //设置颁发者
                .withIssuedAt(new Date()) // 设置颁发时间
                .withExpiresAt(instance.getTime()) //设置过期时间
                .sign(Algorithm.HMAC256(secret));
        return token;
    }

    /**
     * 验证token
     * @param token
     * @return
     */
    public boolean verifyToken(String token) {
        try {
            JWT.require(Algorithm.HMAC256(secret)).build().verify(token);
        }catch (JWTVerificationException e) {
            return false;
        }
        return true;
    }

    /**
     * token解析
     * @param token
     * @return
     */
    public DecodedJWT jwtDecode(String token) {
        try {
            return JWT.require(Algorithm.HMAC256(secret)).build().verify(token);
        }catch (SignatureVerificationException e) {
            throw new RuntimeException("token签名错误！");
        }catch (AlgorithmMismatchException e) {
            throw new RuntimeException("token 算法不匹配");
        }catch (TokenExpiredException e) {
            throw new RuntimeException("token 过期");
        }catch (Exception e) {
            throw new RuntimeException("token解析失败！");
        }

    }
}
